package com.apex.shared.redis.exception;

import lombok.Getter;

/**
 * Redis统一异常处理类
 *
 * @author Apex
 */
@Getter
public class RedisException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    /**
     * Redis操作类型
     */
    private final OperationType operationType;

    /**
     * Redis操作的键
     */
    private final String key;

    /**
     * Redis操作的值（可选）
     */
    private final Object value;

    /**
     * Redis操作的过期时间（可选，单位：秒）
     */
    private final Long expireSeconds;

    public RedisException(String message) {
        super(message);
        this.operationType = null;
        this.key = null;
        this.value = null;
        this.expireSeconds = null;
    }

    public RedisException(String message, Throwable cause) {
        super(message, cause);
        this.operationType = null;
        this.key = null;
        this.value = null;
        this.expireSeconds = null;
    }

    public RedisException(String message, OperationType operationType, String key) {
        super(message);
        this.operationType = operationType;
        this.key = key;
        this.value = null;
        this.expireSeconds = null;
    }

    public RedisException(String message, Throwable cause, OperationType operationType, String key) {
        super(message, cause);
        this.operationType = operationType;
        this.key = key;
        this.value = null;
        this.expireSeconds = null;
    }

    public RedisException(String message, OperationType operationType, String key, Object value) {
        super(message);
        this.operationType = operationType;
        this.key = key;
        this.value = value;
        this.expireSeconds = null;
    }

    public RedisException(String message, Throwable cause, OperationType operationType, String key, Object value) {
        super(message, cause);
        this.operationType = operationType;
        this.key = key;
        this.value = value;
        this.expireSeconds = null;
    }

    public RedisException(String message, OperationType operationType, String key, Object value, Long expireSeconds) {
        super(message);
        this.operationType = operationType;
        this.key = key;
        this.value = value;
        this.expireSeconds = expireSeconds;
    }

    public RedisException(String message, Throwable cause, OperationType operationType, String key, Object value, Long expireSeconds) {
        super(message, cause);
        this.operationType = operationType;
        this.key = key;
        this.value = value;
        this.expireSeconds = expireSeconds;
    }

    /**
     * Redis操作类型枚举
     */
    @Getter
    public enum OperationType {
        GET("获取数据"),
        SET("设置数据"),
        DELETE("删除数据"),
        EXPIRE("设置过期时间"),
        LOCK("加锁操作"),
        UNLOCK("解锁操作"),
        INCREMENT("递增操作"),
        DECREMENT("递减操作"),
        HASH("哈希操作"),
        LIST("列表操作"),
        SET_OPS("集合操作"),
        ZSET("有序集合操作"),
        PUBLISH("发布操作"),
        SUBSCRIBE("订阅操作"),
        PIPELINE("管道操作"),
        TRANSACTION("事务操作");

        private final String description;

        OperationType(String description) {
            this.description = description;
        }
    }

    @Override
    public String getMessage() {
        StringBuilder sb = new StringBuilder(super.getMessage());
        
        if (operationType != null) {
            sb.append(" [操作类型: ").append(operationType.getDescription());
            
            if (key != null) {
                sb.append(", 键: ").append(key);
            }
            if (value != null) {
                sb.append(", 值: ").append(value);
            }
            if (expireSeconds != null) {
                sb.append(", 过期时间: ").append(expireSeconds).append("秒");
            }
            sb.append("]");
        }

        return sb.toString();
    }
} 